#include <interfaces/SocketEventMonitor.h>
#include "../DomainAcceptor.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

// TODO: Move this to central header file
#include <string.h>

namespace Greatewall
{
    namespace Network
    {
        bool
        DomainAcceptor::initDomainAcceptor(std::string& sock_path, int backlog)
        {
            if (_inited)
            {
                // TODO: Error handling
                return false;
            }

            if (sock_path.empty())
            {
                // TODO: Error handling
                return false;
            }

            if (!initDomainSock(sock_path, SERVER, backlog))
            {
                // TODO: Error handling
                return false;
            }

            return true;
        }

        void
        DomainAcceptor::handleInbound()
        {
            sockaddr_un remote;
            memset(&remote, 0, sizeof(remote));

            socklen_t   remote_len = 0;

            SysSockHandler hdl = accept(_hdl, (sockaddr*)&remote, &remote_len);

            if (-1 == hdl)
            {
                // TODO: Error handling
                return;
            }

            // TODO: This is no safe
            // What would happen if the path is exactly 108 char long??
            std::string sock_path = remote.sun_path;

            SystemSocket* sock = createClientHandler(hdl, sock_path);

            if (sock == 0)
            {
                // TODO: Error handling
                return;
            }

            _sock_event_monitor.registerSocket(sock, SocketEventMonitor::IN);
        }
    }
}
